/*read.cpp
 *This program reads specified block on created RAID and saves it to specified file.
 *Created on: 2013.12.24
 *Author: Petrunin D.S.
 */
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <cstring>
#include "base.h"

int readRAID01(FILE* file, int blockN, int numOfDisks, int numOfBlocks,
				int blockS) {
	if (mapping(numOfDisks, numOfBlocks, blockS, false) == 1) return 1;

	int offset = (blockN - 1) * blockS;

	for (int i = 1; i <= (numOfDisks/2); i++)
		fputs(mappedDataArray[i] + offset, file); //read mappedData

	fclose(file);
	if (unmapping(numOfDisks, numOfBlocks, blockS, false) == 1) return 1;
	return 0;
}


int readRAID10(FILE* file, int blockN, int numOfDisks, int numOfBlocks,
				int blockS) {
	if (mapping(numOfDisks, numOfBlocks, blockS, false) == 1) return 1;

	int offset = (blockN - 1) * blockS;

	for (int i = 1; i < numOfDisks; i += 2)
		fputs(mappedDataArray[i] + offset, file); //read mappedData

	fclose(file);
	if (unmapping(numOfDisks, numOfBlocks, blockS, false) == 1) return 1;
	return 0;
}


int main(int argc, char* argv[]) {

	if (argc < 3) {
		cout << "Not enough parameters\n";
		return 1;
	}

	FILE* config = fopen("conf", "r");
	if (config == NULL) {
		cout << "Can't open config file.\n";
		return 1;
	}
	int numOfDisks, numOfBlocks, blockS, RAIDLevel;
	fscanf(config, "%i\n%i\n%i\n%i\n", &numOfDisks, &numOfBlocks, &blockS,
			&RAIDLevel);
	fclose(config);

	if (failedDisk(numOfDisks, false)) {
		cout << "Rebuild RAID.\n";
		return 1;
	}

	int blockN = atoi(argv[1]);
	if ((blockN == 0) || (blockN > numOfBlocks)) {
		cout << "Number of blocks must be 1.." << numOfBlocks << "\n";
		return 1;
	}

	char* fileName = argv[2];
	FILE * file;
	file = fopen(fileName, "wb+");
	if (file == NULL) {
		cout << "Can't create or open file " << file << "\n";
		return 1;
	}

	switch (RAIDLevel) {
	case 0:
		return readRAID01(file, blockN, numOfDisks, numOfBlocks,
				blockS);
	case 1:
		return readRAID10(file, blockN, numOfDisks, numOfBlocks,
				blockS);
	}
}

